import {isObjectValEqual} from "jh-utils";
import {isBoolean, isFunction, isObject} from "lodash-es";
import React from "react";

/**
 * 公用的 getDerivedStateFromProps 处理逻辑。用于受控的组件中，同步更新 props.value 和 props.defaultValue 到 this.state
 * @param nextProps object
 * @param preState object | undefined
 * @param dealDataFunc (changedValue: any) => object; 在这个方法里返回需要更新到 state 里的值。
 *      （注：defaultValue 的处理已经在 getDerivedStateFromPropsFunc 中默认处理，所以这里不用返回了）
 *      dealDataFunc 有一个 changedValue 参数，即 nextProps 中有变化的 value 或 defaultValue 的值。
 *
 * @return {{}|null}
 */
export function getDerivedStateFromPropsFunc(nextProps, preState, dealDataFunc) {
    let needUpdate = false;
    let changedValue = {};
    let moreValue = {};

    // 有 value，说明这是个受控组件，则以 value 为准
    if ('value' in nextProps) {
        needUpdate = true;
        changedValue = nextProps.value;

    } else if ('defaultValue' in nextProps && preState &&
        !isObjectValEqual({defaultValue: nextProps.defaultValue}, {defaultValue: preState.defaultValue})) {
        // 如果是作为非受控组件。当 defaultValue 改变，则更新组件内的数据
        needUpdate = true;
        changedValue = nextProps.defaultValue;
        moreValue = {defaultValue: nextProps.defaultValue,};
    }

    if (needUpdate) {
        if (isFunction(dealDataFunc)) {
            let tmpVales = dealDataFunc(changedValue);
            if (isObject(tmpVales)) {
                moreValue = {...moreValue, ...tmpVales};
            }
        } else {
            moreValue.value = changedValue;
        }
        return moreValue;
    }

    return null;
}

/**
 * 获取“Modal、Popover、Drawer”等弹框的父级容器
 * @param $this
 * @return {HTMLElement}
 */
export function getContainerFunc($this) {
    if ($this.props) {

        if (document.getElementById($this.props.popupContainId)) {
            return document.getElementById($this.props.popupContainId);
        }

        if (document.getElementById($this.props.containId)) {
            return document.getElementById($this.props.containId);
        }

        let {appins} = $this.props;
        if (appins && appins.appUUID && document.getElementById(appins.appUUID)) {
            return document.getElementById(appins.appUUID);
        }
    }
    return document.body;
}